package com.lb.bs.client.adapter.spring;

import com.lb.bs.client.adapter.AbstractStarter;
import com.lb.bs.client.repository.ScanStaticModel;
import com.lb.bs.client.repository.BeanHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;

import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * program: LB-BS-Client
 * author: bsworld.xie
 * create: 2020-01-15 15:10
 * description:
 */
public class SpringStarter extends AbstractStarter implements DisposableBean, BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    private static AtomicInteger ai = new AtomicInteger(1);
    private static final Logger logger = LoggerFactory.getLogger(SpringStarter.class);




    private BeanDefinitionRegistry registry;


    /**
     * 释放资源
     */
    @Override
    public void destroy() {
        super.destroyCore();
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        this.registry = registry;
        logger.info("postProcessBeanDefinitionRegistry(), invoke times:{}",ai.getAndIncrement());
        this.start();
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }

    @Override
    protected void before() {
        ScanStaticModel scanStaticModel = this.scanStaticModel;
        BeanDefinitionRegistry registry = this.registry;
        Set<Class<?>> clazzList = scanStaticModel.getClazzList();
        BeanHolder<Object> holder = BeanHolder.getHolder();
        for (Class<?> clazz : clazzList) {
            Object originBean = holder.getBean(clazz);
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(originBean);
            beanDefinition.setBeanClass(SpringFactoryBean.class);
            beanDefinition.setLazyInit(false);
            beanDefinition.setAbstract(false);
            beanDefinition.setAutowireCandidate(true);
            beanDefinition.setScope("singleton");
            String simpleName = clazz.getSimpleName();
            String preName = simpleName.substring(0, 1).toLowerCase();
            String lastName = simpleName.substring(1);
//            simpleName = "$" + preName + lastName;
            simpleName =  preName + lastName;
            registry.registerBeanDefinition(simpleName, beanDefinition);
        }
    }
}
